home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / dir / browser2.41 / c / for.c < prev    next >
C/C++ Source or Header  |  1993-03-18  |  20KB  |  710 lines

  1. /*
  2.  *    Copyright © 1991 by S.R. & P.C.
  3.  *
  4.  *    Created:    23 May 1992     12:00:40
  5.  *    Modified:    18 Mar 1993  22:35:21
  6.  *
  7.  * Make>> sc <file>.c
  8.  * Make>> SLink LIB:cs.o <file>.o SC SD BATCH NOICONS LIB LIB:Startup.lib LIB:String.lib
  9.  */
  10.  
  11. #include <libraries/WhatIsBase.h>
  12. #include <proto/WhatIs.h>
  13.  
  14.  
  15. struct Library *WhatIsBase = NULL;
  16.  
  17. /* have problem whith stack size so I reduce string len */
  18. #define MAXSTRINGLEN 255/2
  19. #define MAXCMDLEN 512/2
  20.  
  21. #define MAX_PATHLEN 512
  22. /*ULONG const MaxStringLen = MAXSTRINGLEN;*/
  23.  
  24. #define MAXNUMARGS 64
  25. #define MAXDEFAULTLEN 512/2
  26.  
  27. /* char used in the filetype spec string */
  28. #define NOTFileType '!'
  29. #define ONLYFileType '%'
  30. #define WHITHSubSub '#'
  31.  
  32. STRPTR Template = "Pattern/M,Files/K,Dirs/K,Since/K,Before/K,MinSize/K/N,MaxSize/K/N,PosProtect/K,NegProtect/K,Type/K,ALL/K/S,ASYNC/K/S,READSIZE/N,SHOWBYTE/N,D=DEEP/K/N,SFT=SHOWFILETYPE/K/S,DO/K/F";
  33.  
  34. #define ARG_NameA    0
  35. #define ARG_Files        1
  36. #define ARG_Dirs        2
  37. #define ARG_Since        3
  38. #define ARG_Before    4
  39. #define ARG_MinSize    5
  40. #define ARG_MaxSize    6
  41. #define ARG_PosProtect    7
  42. #define ARG_NegProtect    8
  43. #define ARG_Type        9
  44. #define ARG_ALL        10
  45. #define ARG_ASYNC        11
  46. #define ARG_READSIZE    12
  47. #define ARG_SHOWBYTE    13
  48. #define ARG_DEEPWHATIS    14
  49. #define ARG_SHOWFILETYPE    15
  50. #define ARG_CMD        16
  51. #define ARG_ENDARG    17
  52.  
  53. STRPTR CliHelp = "For V2.0 © 1992 S.R. & P.C.\n\
  54. Usage: For <Pattern> [FILES <MATCH|YES|NO>]  [DIRS <MATCH|YES|NO>] [Since <Date>] [Before <Date>] [MinSize <Number>] [MaxSize <Number>] [PosProtect <L|C|H|S|P|A|R|W|E|D>] [NegProtect <L|C|H|S|P|A|R|W|E|D>] [Type <FileType0...FileType9|%=ONLY|*=SUB|!=EXLC>] [ALL] [ASYNC] [READSIZE] [SHOWBYTE] [DEEPWHATIS] [SHOWFILETYPE] [DO <Command [args] [,Command [args] [,...]]>]\n";
  55.  
  56. /*******************************************************/
  57. /* not in dos.h !! */
  58. #define    FIBB_HIDDEN        7
  59. #define    FIBF_HIDDEN        (1<<FIBB_HIDDEN)
  60.  
  61. /* it is my own definition: not standard */
  62. #define    FIBB_COMMENT    8
  63. #define    FIBF_COMMENT    (1<<FIBB_COMMENT)
  64. #define    FIBB_LINK        9
  65. #define    FIBF_LINK        (1<<FIBB_LINK)
  66.  
  67.  
  68. #define PATTERN_BUF_SIZE    32
  69. #define MAX_FTS                10    /* Max FileTypeSpec in SelectInfo */
  70.  
  71. struct FileTypeSpec {
  72.     FileType fs_FileType;
  73.     UWORD fs_Flags;
  74. };
  75.  
  76. /* FileTypeSpec flags */
  77. #define FTSF_EXCLUDETYPE    0x0001    /* Exclude this type (otherwise include) */
  78. #define FTSF_WITHSUBTYPES    0x0002    /* Affect Include/Exclude to subtypes */
  79.  
  80.  
  81. struct SelectInfo {
  82.     UBYTE si_Pattern[PATTERN_BUF_SIZE];    /* Pattern                        */
  83.     UBYTE si_PatTok[PATTERN_BUF_SIZE];    /* PreParsed pattern            */
  84.     LONG si_MinSize;    /* Show files bigger than that    */
  85.     LONG si_MaxSize;    /*   and smaller than that        */
  86.     struct DateStamp si_SinceDate;    /* Show files newer than that    */
  87.     struct DateStamp si_BeforeDate;    /*   and older than that        */
  88.     LONG si_SinceSecs;    /* date in seconds                */
  89.     LONG si_BeforeSecs;    /* date in seconds                */
  90.     UWORD si_PosProtect;    /* Show files that have these bits set   */
  91.     UWORD si_NegProtect;    /* Show files that have these bits clear */
  92.     struct FileTypeSpec si_FileTypes[MAX_FTS];    /* Include and Exclude file types */
  93.     UWORD si_NumFts;    /* Number of FileTypeSpec in previous array */
  94.     UWORD si_Flags;        /* Flags. See below                */
  95. };
  96.  
  97. /* SelectInfo flags */
  98.  
  99. #define SI_ALL_FILES        0x0001
  100. #define SI_MATCH_FILES        0x0002
  101. #define SI_ALL_DIRS            0x0004
  102. #define SI_MATCH_DIRS        0x0008
  103. #define SI_AFFECT_SUBDIRS    0x0010
  104. #define SI_NAME                0x0020
  105. #define SI_SIZE                0x0040
  106. #define SI_SINCEDATE        0x0080
  107. #define SI_BEFOREDATE        0x0100
  108. #define SI_POSPROTECTION    0x0200
  109. #define SI_NEGPROTECTION    0x0400
  110. //
  111. #define SI_INVERT            0x0800    /* Invert filters */
  112. //
  113. #define SI_AFFECT_INFO        0x1000    /* do actions on .info files too (WARNING: also defined as an option (for menu)) */
  114. #define SI_POSFILETYPE        0x2000
  115. #define SI_NEGFILETYPE        0x4000
  116.  
  117. #define SI_FILETYPE            (SI_POSFILETYPE|SI_NEGFILETYPE)
  118. #define SI_MATCHBITS        (SI_NAME|SI_SIZE|SI_SINCEDATE|SI_BEFOREDATE|SI_POSPROTECTION|SI_NEGPROTECTION|SI_FILETYPE)
  119. /*************************************************/
  120.  
  121. /*#pragma tagcall WhatIsBase WhatIs 1E 9802*/
  122. FileType _WhatIsTags(char *Name, Tag FirstTag,...)
  123. {
  124.     return (WhatIsBase) ? WhatIs(Name, (struct TagItem *) & FirstTag) : TYPE_UNSCANNED;
  125. }
  126.  
  127.  
  128. /*************************************************/
  129. /*
  130.  *    return pointer to the first non blank char in a string, or to the '\0' if
  131.  *    the string is empty
  132.  */
  133.  
  134. static char *FirstNonBlank(char *buf)
  135. {
  136.     while (*buf && *buf == ' ')
  137.         buf++;
  138.     return buf;
  139. }
  140.  
  141.  
  142. /* check if buffer is empty or not */
  143.  
  144. static BOOL IsEmpty(char *buf)
  145. {
  146.     return (BOOL) ((*FirstNonBlank(buf)) ? FALSE : TRUE);
  147. }
  148.  
  149.  
  150. static BOOL String2Date(char *src, struct DateStamp * ds)
  151. {
  152.     struct DateTime *dt;
  153.     BOOL Ok = TRUE;
  154.     char *s1, *s2;
  155.     char buf[PATTERN_BUF_SIZE];
  156.  
  157.     if (!(dt = AllocMem(sizeof(struct DateTime), MEMF_PUBLIC | MEMF_CLEAR)))
  158.         return FALSE;
  159.     strcpy(buf, src);
  160.     s1 = s2 = FirstNonBlank(buf);
  161.     if (*s1) {
  162.         dt->dat_StrDate = s1;
  163.         while (*s2 && *s2 != ' ')
  164.             s2++;
  165.         if (*s2) {
  166.             *s2++ = '\0';
  167.             s2 = FirstNonBlank(s2);
  168.         }
  169.         if (*s2) {
  170.             dt->dat_StrTime = s2;
  171.             if (!StrToDate(dt))
  172.                 Ok = FALSE;
  173.         }
  174.         else if (!StrToDate(dt)) {
  175.             dt->dat_StrDate = NULL;
  176.             dt->dat_StrTime = s1;
  177.             if (!StrToDate(dt))
  178.                 Ok = FALSE;
  179.         }
  180.         if (Ok)
  181.             *ds = dt->dat_Stamp;
  182.     }
  183.     FreeMem(dt, sizeof(struct DateTime));
  184.     return Ok;
  185. }
  186.  
  187. /* Convert DateStamp into a number of seconds since 1-Jan-78 */
  188.  
  189. long Date2Secs(struct DateStamp * ds)
  190. {
  191.     return ds->ds_Days * 86400 + ds->ds_Minute * 60 + ds->ds_Tick / 50;
  192. }
  193.  
  194. /*************************************************/
  195.  
  196. long __regargs _Main(void)
  197. {
  198.     char *ArgV[MAXNUMARGS];
  199.     struct RDArgs *RA;
  200.     struct RDArgs *DefaultRDArgs;
  201.     LONG RC = 20;        /* assumle the worst */
  202.  
  203.     if (DOSBase->dl_lib.lib_Version < 37)
  204.         return 20;
  205.  
  206.  
  207.     if (RA = AllocDosObject(DOS_RDARGS, NULL)) {
  208.         memset(ArgV, 0, MAXNUMARGS * sizeof(APTR));
  209.         RA->RDA_ExtHelp = CliHelp;
  210.         /* first read default */
  211.         /* getting the default string */
  212.         if (DefaultRDArgs = AllocDosObject(DOS_RDARGS, NULL)) {
  213.             UBYTE Default[MAXDEFAULTLEN];
  214.  
  215.             if ((DefaultRDArgs->RDA_Source.CS_Length = GetVar("For.DefOpts", Default, MAXDEFAULTLEN - 1, 0L)) > 0) {
  216.                 /* let ReadArgs() allocate neccesary buffer sinc I use diferrent RDArgs for Default and CLI opts */
  217.  
  218.                 /* Ok I succefuly read a Default Option string now parse it */
  219.                 Default[DefaultRDArgs->RDA_Source.CS_Length++] = '\n';    /* this is need by ReadArgs() */
  220.                 Default[DefaultRDArgs->RDA_Source.CS_Length] = '\0';    /* this is need by ReadArgs() */
  221.                 DefaultRDArgs->RDA_Source.CS_Buffer = Default;
  222.                 DefaultRDArgs->RDA_Source.CS_CurChr = 0;
  223.                 DefaultRDArgs->RDA_Flags = RDAF_NOPROMPT;
  224.                 if (!ReadArgs(Template, (long *) ArgV, DefaultRDArgs)) {
  225.                     PutStr("Error in Default:");
  226.                     PrintFault(IoErr(), NULL);
  227.                     memset(ArgV, 0, MAXNUMARGS * sizeof(APTR));
  228.                 }
  229.                 DefaultRDArgs->RDA_Source.CS_Buffer = NULL;    /* Now ReadArgs() from Command line */
  230.                 /* the ArgV is leaving unchanged: the second ReadArgs() take actual value as default */
  231.             }
  232.         }
  233.         /* Let ReadArgs() allocate necessay buffer rather using stack space */
  234.         if (ReadArgs(Template, (long *) ArgV, RA))
  235.             RC = Main(ArgV, NULL);
  236.         else
  237.             PrintFault(IoErr(), NULL);
  238.         FreeDosObject(DOS_RDARGS, RA);
  239.         /* Free RDargs now I don't need the option value */
  240.         if (DefaultRDArgs)
  241.             FreeDosObject(DOS_RDARGS, DefaultRDArgs);
  242.     }
  243.     return RC;
  244. }
  245.  
  246. /**** ****/
  247.  
  248. void RemoveDir(char FullDir[])
  249. {
  250.     char *s;
  251.  
  252.     if (s = PathPart(FullDir))
  253.         *s = '\0';
  254. }
  255.  
  256. void PrintByte(UBYTE Buffer[], long BufLen, UBYTE Num)
  257. {
  258.     register short i;
  259.  
  260.     for (i = 0; i < Num && i < BufLen; i++)
  261.         Printf("%02lx", (long) Buffer[i]);
  262. }
  263.  
  264. /*
  265.  *    Parse a line that may contain comas. Backslash ('\') is the override char.
  266.  */
  267. void ParseCmdLine(char *cmd)
  268. {
  269.     char *s, *d, c;
  270.  
  271.     s = d = cmd;
  272.     while (c = *d++ = *s++) {
  273.         if (c == '\\')
  274.             *(d - 1) = *s++;
  275.         else if (c == ',')
  276.             *(d - 1) = '\n';
  277.     }
  278. }
  279.  
  280. void MakeFmt(char Cmd[], char CmdFmt[])
  281. {
  282.     char *s;
  283.     BOOL Found = FALSE;
  284.  
  285.     strcpy(CmdFmt, Cmd);
  286.     ParseCmdLine(CmdFmt);    /* Replace , by \n to separate commands */
  287.     s = CmdFmt;
  288.     while (*s) {
  289.         if (*s == '%' && *(s + 1) == '%') {
  290.             *(s + 1) = 's';
  291.             Found = TRUE;
  292.         }
  293.         s++;
  294.     }
  295.     if (!Found)
  296.         StrnCat(CmdFmt, " %s", MAXCMDLEN - 1);
  297. }
  298.  
  299. UWORD ProtectBit(char P[])
  300. {
  301.     UWORD PB = 0;
  302.  
  303.     while (*P) {
  304.         switch (*P) {
  305.         case 'L':
  306.         case 'l':
  307.             PB |= FIBF_LINK;    /* another magic bit! */
  308.             break;
  309.         case 'C':
  310.         case 'c':
  311.             PB |= FIBF_COMMENT;    /* our magic bit! */
  312.             break;
  313.         case 'H':
  314.         case 'h':
  315.             PB |= FIBF_HIDDEN;
  316.             break;
  317.         case 'S':
  318.         case 's':
  319.             PB |= FIBF_SCRIPT;
  320.             break;
  321.         case 'P':
  322.         case 'p':
  323.             PB |= FIBF_PURE;
  324.             break;
  325.         case 'A':
  326.         case 'a':
  327.             PB |= FIBF_ARCHIVE;
  328.             break;
  329.         case 'R':
  330.         case 'r':
  331.             PB |= FIBF_READ;
  332.             break;
  333.         case 'W':
  334.         case 'w':
  335.             PB |= FIBF_WRITE;
  336.             break;
  337.         case 'E':
  338.         case 'e':
  339.             PB |= FIBF_EXECUTE;
  340.             break;
  341.         case 'D':
  342.         case 'd':
  343.             PB |= FIBF_DELETE;
  344.             break;
  345.         default:    /* nothing to do */
  346.             break;
  347.         }
  348.         P++;
  349.     }
  350.  
  351.     return PB;
  352. }
  353.  
  354. UWORD EasyProtect(LONG Protection)
  355. {
  356.     return (UWORD) ((Protection ^ 0x0F) & 0x00FF);    /* Complement 4 lower bits so all work the same way */
  357. }
  358.  
  359. BOOL Match(struct SelectInfo * SelectInfo, struct FileInfoBlock * FIB)
  360. {
  361.     if (FIB->fib_DirEntryType < 0) {    /* this is a file */
  362.         if (SelectInfo->si_Flags & SI_ALL_FILES)
  363.             return TRUE;
  364.         else if (!(SelectInfo->si_Flags & SI_MATCH_FILES))
  365.             return FALSE;
  366.     }
  367.     else {            /* Dir */
  368.         if (SelectInfo->si_Flags & SI_ALL_DIRS)
  369.             return TRUE;
  370.         else if (!(SelectInfo->si_Flags & SI_MATCH_DIRS))
  371.             return FALSE;
  372.     }
  373.     if (SelectInfo->si_Flags & SI_NAME) {
  374.         if (!MatchPatternNoCase(SelectInfo->si_PatTok, FIB->fib_FileName))
  375.             return FALSE;
  376.     }
  377.     {
  378.         long Secs = Date2Secs(&FIB->fib_Date);
  379.  
  380.         if (SelectInfo->si_Flags & SI_SINCEDATE) {
  381.             if (Secs < SelectInfo->si_SinceSecs)
  382.                 return FALSE;
  383.         }
  384.         if (SelectInfo->si_Flags & SI_BEFOREDATE) {
  385.             if (Secs > SelectInfo->si_BeforeSecs)
  386.                 return FALSE;
  387.         }
  388.     }
  389.     if (FIB->fib_Size < SelectInfo->si_MinSize)
  390.         return FALSE;
  391.     if (SelectInfo->si_MaxSize && (FIB->fib_Size > SelectInfo->si_MaxSize))
  392.         return FALSE;
  393.     {
  394.         UWORD Protection = EasyProtect(FIB->fib_Protection);
  395.  
  396.         if (SelectInfo->si_Flags & SI_POSPROTECTION) {
  397.             if (!(Protection & SelectInfo->si_PosProtect))
  398.                 return FALSE;
  399.         }
  400.         if (SelectInfo->si_Flags & SI_NEGPROTECTION) {
  401.             if ((Protection & SelectInfo->si_NegProtect))
  402.                 return FALSE;
  403.         }
  404.     }
  405.  
  406.     return TRUE;
  407. }
  408.  
  409. BOOL MatchFileType(struct SelectInfo * SelectInfo, struct FileInfoBlock * FIB, FileType Type)
  410. {
  411.     if (WhatIsBase && (SelectInfo->si_Flags & SI_FILETYPE)) {
  412.         UWORD Flags, i;
  413.  
  414.         for (i = 0; i < SelectInfo->si_NumFts; i++) {
  415.             Flags = SelectInfo->si_FileTypes[i].fs_Flags;
  416.             if (!CmpFileType(SelectInfo->si_FileTypes[i].fs_FileType, Type))
  417.                 return (BOOL) ((Flags & FTSF_EXCLUDETYPE) ? FALSE : TRUE);
  418.             if ((Flags & FTSF_WITHSUBTYPES) && IsSubTypeOf(Type, SelectInfo->si_FileTypes[i].fs_FileType))
  419.                 return (BOOL) ((Flags & FTSF_EXCLUDETYPE) ? FALSE : TRUE);
  420.         }
  421.         if (SelectInfo->si_Flags & SI_POSFILETYPE)
  422.             return FALSE;    /* no match within include FileTypes, exclude file */
  423.         else
  424.             return TRUE;    /* Only exclude types, and not found in them, include file */
  425.     }
  426.     return TRUE;
  427. }
  428.  
  429.  
  430. long __regargs Main(char *ArgV[], struct WBStartup *WBenchMsg)
  431. {
  432.     LONG rc = 0;
  433.     long ReadSize = 480;
  434.     UBYTE ShowByte = 8;
  435.     ULONG Deep = 0;
  436.     BOOL ShowFileType;
  437.     char FmtCmd[MAXCMDLEN], Cmd[MAXCMDLEN];
  438.     struct SelectInfo SelectInfo;
  439.  
  440.     WhatIsBase = OpenLibrary("whatis.library", 3L);
  441.  
  442.     memset(&SelectInfo, 0, sizeof(SelectInfo));
  443.     if (ArgV[ARG_Files]) {
  444.         if (!Stricmp(ArgV[ARG_Files], "MATCH"))
  445.             SelectInfo.si_Flags |= SI_MATCH_FILES;
  446.         else if (!Stricmp(ArgV[ARG_Files], "YES"))
  447.             SelectInfo.si_Flags |= SI_ALL_FILES;
  448.     }
  449.     else            /* set default */
  450.         SelectInfo.si_Flags |= SI_MATCH_FILES;
  451.     if (ArgV[ARG_Dirs]) {
  452.         if (!Stricmp(ArgV[ARG_Dirs], "MATCH"))
  453.             SelectInfo.si_Flags |= SI_MATCH_DIRS;
  454.         else if (!Stricmp(ArgV[ARG_Dirs], "YES"))
  455.             SelectInfo.si_Flags |= SI_ALL_DIRS;
  456.     }
  457.     else            /* set default */
  458.         SelectInfo.si_Flags |= SI_MATCH_DIRS;
  459.     if (ArgV[ARG_Since]) {
  460.         struct DateStamp DateStamp;
  461.  
  462.         String2Date(ArgV[ARG_Since], &DateStamp);
  463.         SelectInfo.si_SinceDate = DateStamp;
  464.         SelectInfo.si_SinceSecs = Date2Secs(&DateStamp);
  465.         SelectInfo.si_Flags |= SI_SINCEDATE;
  466.     }
  467.     if (ArgV[ARG_Before]) {
  468.         struct DateStamp DateStamp;
  469.  
  470.         String2Date(ArgV[ARG_Before], &DateStamp);
  471.         SelectInfo.si_BeforeDate = DateStamp;
  472.         SelectInfo.si_BeforeSecs = Date2Secs(&DateStamp);
  473.         SelectInfo.si_Flags |= SI_BEFOREDATE;
  474.     }
  475.     if (ArgV[ARG_MinSize])
  476.         SelectInfo.si_MinSize = *(ULONG *) ArgV[ARG_MinSize];
  477.     if (ArgV[ARG_MaxSize])
  478.         SelectInfo.si_MaxSize = *(ULONG *) ArgV[ARG_MaxSize];
  479.     if (ArgV[ARG_PosProtect]) {
  480.         SelectInfo.si_Flags |= SI_POSPROTECTION;
  481.         SelectInfo.si_PosProtect = ProtectBit(ArgV[ARG_PosProtect]);
  482.     }
  483.     if (ArgV[ARG_NegProtect]) {
  484.         SelectInfo.si_Flags |= SI_NEGPROTECTION;
  485.         SelectInfo.si_NegProtect = ProtectBit(ArgV[ARG_NegProtect]);
  486.     }
  487.     if (ArgV[ARG_Type] && WhatIsBase) {
  488.         UBYTE NumFT = 0;
  489.         UWORD Flags = 0;
  490.         char *c;
  491.  
  492.         for (c = ArgV[ARG_Type]; *c; c++) {
  493.             Printf("\"%s\"\n", c);
  494.             switch (*c) {
  495.             case ONLYFileType:
  496.                 Flags &= ~FTSF_EXCLUDETYPE;
  497.                 break;
  498.             case NOTFileType:
  499.                 Flags |= FTSF_EXCLUDETYPE;
  500.                 break;
  501.             case WHITHSubSub:
  502.                 Flags |= FTSF_WITHSUBTYPES;
  503.                 break;
  504.             case '(':    /* for ReadArgs()/Template reaseon, the quote '"' can't be used */
  505.                 {
  506.                     char IDType[100];
  507.                     char *i = IDType;
  508.  
  509.                     c++;    /* skip '(' */
  510.                     while (*c != ')')
  511.                         *i++ = *c++;    /* copy until ')' */
  512.                     *i = '\0';    /* NULL terminate the string */
  513.                     /* BUG: the SAS don't warn on this : i = '\0' */
  514.  
  515.                     SelectInfo.si_FileTypes[NumFT].fs_FileType = GetIDType(IDType);
  516.                     SelectInfo.si_FileTypes[NumFT].fs_Flags = Flags;
  517.                     if (TYPE_UNKNOWNIDSTRING == SelectInfo.si_FileTypes[NumFT].fs_FileType)
  518.                         Printf("Unknown FileType:\"%s\"\n", IDType);
  519.                     else
  520.                         NumFT++;
  521.                 }
  522.                 break;
  523.             case ')':
  524.                 /* just the mark of the end of and FileType ident, nothing to do */
  525.             case ',':
  526.                 /* just a separator, nothing to do */
  527.                 break;
  528.                   delault:
  529.                 Printf("FileType spec have errors at:%s\n", c);
  530.             }
  531.         }
  532.         SelectInfo.si_NumFts = NumFT;
  533.         SelectInfo.si_Flags |= (Flags & FTSF_EXCLUDETYPE) ? SI_NEGFILETYPE : SI_POSFILETYPE;
  534.     }
  535.  
  536.     if (ArgV[ARG_READSIZE])
  537.         ReadSize = *(long *) ArgV[ARG_READSIZE];
  538.     if (ArgV[ARG_SHOWBYTE])
  539.         ShowByte = (UBYTE) * (long *) ArgV[ARG_SHOWBYTE];
  540.  
  541.     if (ArgV[ARG_DEEPWHATIS])
  542.         Deep = *(long *) ArgV[ARG_DEEPWHATIS];
  543.  
  544.     ShowFileType = (BOOL) ArgV[ARG_SHOWFILETYPE];
  545.     if (ArgV[ARG_CMD])
  546.         MakeFmt(ArgV[ARG_CMD], FmtCmd);
  547.     else
  548.         ShowFileType = TRUE;    /* If user don't supply cmd I suppose he call "For" for somthing */
  549.  
  550.     /* SASBUG: this line generte incorrect code:
  551.          move.l 03c(a5), a0
  552.          move #1,(a0)
  553.          ( BOOL )ArgV[ ARG_SHOWFILETYPE] = TRUE;
  554.     */
  555.     {
  556.         LONG ReturnCode = RETURN_ERROR;
  557.         FileType Type = TYPE_UNSCANNED;
  558.         char FullDir[MAXSTRINGLEN];
  559.         BPTR InputFH, OutputFH;
  560.         BPTR InputLock, OutputLock;
  561.         UBYTE *Buffer;
  562.  
  563.         //BPTR InitialDir;
  564.  
  565.         FullDir[0] = '\0';
  566.         //InitialDir = Lock("", ACCESS_READ);
  567.         //CurrentDir(((struct Process *) SysBase->ThisTask)->pr_CurrentDir);
  568.         InputFH = Input();
  569.         OutputFH = Output();
  570.         if (ArgV[ARG_ASYNC]) {
  571.             InputLock = DupLockFromFH(Input());
  572.             OutputLock = DupLockFromFH(Output());
  573.         }
  574.         if (Buffer = AllocVec(ReadSize + 1, MEMF_ANY)) {
  575.             struct AnchorPath *AP;
  576.  
  577.             if (AP = AllocVec(sizeof(struct AnchorPath) + MAX_PATHLEN, MEMF_ANY | MEMF_CLEAR)) {
  578.                 char Buf[MAXSTRINGLEN];
  579.                 char *Pat;
  580.                 UBYTE i;
  581.  
  582.                 AP->ap_BreakBits = SIGBREAKF_CTRL_C;    /* Break on these bits    */
  583.                 AP->ap_Strlen = MAX_PATHLEN;
  584.                 AP->ap_Flags = (ArgV[ARG_ALL]) ? APF_DODOT : APF_DODOT | APF_DOWILD;    /* allow convertion of '.' to CurrentDir */
  585.                 /*  Well  I have one probleme here:  how corectly handle the
  586.                     ALL  flags:  if the user specify a pattern the MatchNext()
  587.                     hide  all  file  and  DIRS  which  don't  match to the
  588.                     pattern,  so  I  don't  see  dir  and  in  fact can't ask
  589.                     MatchNext()  to  enter it.  This limitation is STUPID and
  590.                     important  liumitation.   I  hope is only because I don't
  591.                     know how to do it.  I hope...
  592.                 */
  593.                 for (i = 0, Pat = ((char **) ArgV[ARG_NameA])[0]; Pat; i++, Pat = ((char **) ArgV[ARG_NameA])[i]) {
  594.                     char ScanDir[MAXSTRINGLEN] =
  595.                     {'#', '?', '\0'};
  596.                     BOOL DoIt = TRUE;
  597.  
  598.                     {
  599.                         char *FilePattern;
  600.  
  601.                         FilePattern = FilePart(Pat);
  602.                         if (*FilePattern) {
  603.                             SelectInfo.si_Flags |= SI_NAME;
  604.                             strcpy(SelectInfo.si_Pattern, FilePattern);
  605.                             ParsePatternNoCase(FilePattern, SelectInfo.si_PatTok, PATTERN_BUF_SIZE);
  606.                         }
  607.                         *FilePattern = '\0';    /* terminate the full name at end of path */
  608.                         strcpy(ScanDir, Pat);
  609.                         StrCat(ScanDir, "#?");
  610.                     }
  611.                     for (ReturnCode = MatchFirst(ScanDir, AP);
  612.                          ReturnCode == 0;
  613.                          ReturnCode = MatchNext(AP)
  614.                         ) {
  615.                         if (AP->ap_Flags & APF_DirChanged) {
  616.                         }
  617.                         if (AP->ap_Info.fib_DirEntryType > 0) {
  618.                             if (AP->ap_Flags & APF_DIDDIR) {
  619.                                 RemoveDir(FullDir);
  620.                                 Printf("\"%s\"\n", FullDir);
  621.                                 DoIt = FALSE;    /* we have treated this dir before entering in it so don't treat it twice */
  622.                             }
  623.                             else if (ArgV[ARG_ALL]) {
  624.                                 AddPart(FullDir, AP->ap_Info.fib_FileName, MAXSTRINGLEN);
  625.                                 Printf("\"%s\"\n", FullDir);
  626.  
  627.                                 /* make it enter the directory */
  628.                                 AP->ap_Flags |= APF_DODIR;
  629.                             }
  630.                             /* clear the completed directory flag */
  631.                             AP->ap_Flags &= ~APF_DIDDIR;
  632.                         }
  633.                         /* Here is code for handling each particular file */
  634.                         if (DoIt && Match(&SelectInfo, &AP->ap_Info)) {
  635.                             long Readed;
  636.  
  637.                             SPrintf(Buf, "\"%s\"", AP->ap_Buf);
  638.                             if (Deep) {
  639.                                 if (AP->ap_Info.fib_DirEntryType <= 0) {
  640.                                     BPTR FH;
  641.  
  642.                                     if (FH = Open(AP->ap_Buf, MODE_OLDFILE)) {
  643.                                         Readed = Read(FH, Buffer, ReadSize);
  644.                                         Buffer[Readed] = '\0';    /* whatis.library need that */
  645.                                         Type = _WhatIsTags(AP->ap_Buf, WI_Deep, Deep, WI_FIB, &AP->ap_Info, WI_Buffer, Buffer, WI_BufLen, Readed, TAG_DONE);
  646.                                         Close(FH);
  647.                                     }
  648.                                     else
  649.                                         Type = _WhatIsTags(AP->ap_Buf, WI_Deep, Deep, WI_FIB, &AP->ap_Info, TAG_DONE);
  650.                                 }
  651.                                 else
  652.                                     Type = _WhatIsTags(AP->ap_Buf, WI_Deep, Deep, WI_FIB, &AP->ap_Info, TAG_DONE);
  653.                             }
  654.                             else
  655.                                 Type = _WhatIsTags(AP->ap_Buf, WI_Deep, LIGHTTYPE, WI_FIB, &AP->ap_Info, TAG_DONE);
  656.  
  657.                             if (MatchFileType(&SelectInfo, &AP->ap_Info, Type)) {
  658.                                 if (ShowFileType) {
  659.                                     Printf("%-32s\t", AP->ap_Info.fib_FileName);    /* due my print of dir herarhy, only print base name here */
  660.                                     Printf("%-9s \t", GetIDString(Type));
  661.                                     if (AP->ap_Info.fib_DirEntryType <= 0)
  662.                                         PrintByte(Buffer, Readed, ShowByte);
  663.                                     PutStr("\n");
  664.                                 }
  665.  
  666.                                 if (ArgV[ARG_CMD]) {
  667.                                     if (ArgV[ARG_ASYNC]) {
  668.                                         /* Need to do this because Async mode close the Input/Output */
  669.                                         InputFH = OpenFromLock(InputLock);
  670.                                         OutputFH = OpenFromLock(OutputLock);
  671.                                     }
  672.                                     /* Allow 5 %% in cmd */
  673.                                     SPrintf(Cmd, FmtCmd, Buf, Buf, Buf, Buf, Buf);    /* building comand line */
  674.                                     SystemTags(Cmd,
  675.                                            SYS_Input, InputFH,
  676.                                            SYS_Output, OutputFH,
  677.                                            SYS_Asynch, ArgV[ARG_ASYNC],
  678.                                            SYS_UserShell, TRUE,
  679.                                            TAG_DONE
  680.                                         );
  681.                                 }
  682.                             }
  683.                         }
  684.                         DoIt = TRUE;
  685.                     }
  686.                     MatchEnd(AP);    /* This absolutely, positively must be called, all of the time. */
  687.                     if (ReturnCode != ERROR_NO_MORE_ENTRIES) {
  688.                         PrintFault(ReturnCode, NULL);
  689.                     }
  690.                     //CurrentDir(InitialDir);
  691.                 }
  692.                 FreeVec(AP);
  693.             }
  694.             FreeVec(Buffer);
  695.         }
  696.         else
  697.             PutStr("Can't allocate Memory for Buffer\n");
  698.         //UnLock(InitialDir);
  699.         if (ArgV[ARG_ASYNC]) {
  700.             UnLock(InputLock);
  701.             UnLock(OutputLock);
  702.         }
  703.     }
  704.  
  705.     if (WhatIsBase)
  706.         CloseLibrary((struct Library *) WhatIsBase);
  707.  
  708.     return rc;
  709. }
  710.